\section{The method}

当笔者开始学习C语言，以及日后学习\Cpp的时候，笔者经常会编写小段的代码，编译它们，并查看生成的汇编语言代码。这一行为让笔者很轻易就理解了自己所写的代码究竟做了什么。
\footnote{事实上，笔者至今仍在不理解一段代码的作用时这样做。}
笔者这么做了许多许多次，因此，\CCpp代码和编译器所生成的汇编代码的对应关系，深深印刻在了笔者的脑中。
在脑海中立刻构建出C语言程序及其函数的大体结构，也因此变得很轻松。
这一技巧，可能对其他人也有帮助吧。

%There are a lot of examples for both x86/x64 and ARM.
%Those who already familiar with one of architectures, may freely skim over pages.

有时在本书中，我会使用一些旧版本的编译器，这是为了生成最短(或最简单)的代码段。
\ac{TBT}.
\section*{练习}

当笔者研究汇编语言的时候，经常编译较短的C函数，并尝试将这些C函数逐渐手写为汇编代码，只为让生成的代码尽可能地短。
这一行为在现实世界中可能已经意义不大，因为人类在代码的优化效率上远远不如最新的编译器。但是，这仍是提升对于汇编语言的理解能力的极好手段。
因此，请随意试着修改本书中的任意一段代码，试着让它变得更短吧。
但是，请不要忘记测试你所写下的代码。

% rewrote to show that debug\release and optimisations levels are orthogonal concepts.
\section*{优化等级和调试信息}

源代码可以被不同的编译器以不同的优化等级编译。编译器通常有3个优化等级(1至3)，0级表示不进行优化。
优化包括对“代码占据空间”的优化和对“代码执行速度”的优化。
无优化的编译器，可以更快地生成代码，并且产生的代码更具有可读性(尽管显得有一些啰嗦)。
而具有优化能力的编译器，通常生成代码的速度更慢，但会生成运行速度更快的代码(尽管并不必那么简洁)。
除优化等级外，编译器还具有在生成的文件中添加额外的调试信息的能力，使对于生成代码的调试因此变得更加简单。
Debug模式下生成的代码，有一个重要的性质，就是保留了每一行源代码和对应的机器语言代码的地址的联系。
另一方面，编译器的优化倾向于删除掉这种联系，在最终生成的机器码中无法找到这种联系的存在。
逆向工程师可能碰到其中的任意一种情况，因为开发者可能打开也可能关闭编译器的优化选项。
因此，可能的话，笔者会在书中同时给出Debug模式和Release模式的代码以供参考。
